<?php
class XA_XHTML_Form extends XA_XHTML {

	public $field_list = array();
	public $action;
	public $has_file = false;
	public $title;
	public $error_list = array();
	public $alert_list = array();
	public $group_list = array();
	public $form_template;
	public $form_data = array();
	public $method = 'post';
	public static $set_field_type_list = array('set', 'multilivesearch', 'radio');



	public function addText($name, $size = null, $value = null) {
		$this->field_list[$name] = array('type' => 'text', 'value' => $value);

		if ($size) {
			$this->field_list[$name]['size'] = $size;
		}
	}



	public function addFile($name) {
		$this->has_file = true;
		$this->field_list[$name] = array('type' => 'file');
	}



	public function addHidden($name, $value = null) {
		$this->field_list[$name] = array('type' => 'hidden', 'value' => $value);
	}



	public function addTextarea($name, $value = null) {
		$this->field_list[$name] = array('type' => 'textarea', 'value' => $value);
	}



	public function addSubmit($name, $value) {
		$this->field_list[$name] = array('type' => 'submit', 'value' => $value);
	}



	public function addCheckbox($name, $value = null) {
		$this->field_list[$name] = array('type' => 'checkbox', 'value' => $value);
	}



	public function addSet($name, $option_list, $value_list = null) {
		$this->field_list[$name] = array('type' => 'set', 'value_list' => $value_list, 'option_list' => $option_list);
	}



	public function addRadio($name, $option_list, $value = null) {
		$this->field_list[$name] = array('type' => 'radio', 'value' => $value, 'option_list' => $option_list);
	}



	public function addSelect($name, $option_list, $value = null) {
		$this->field_list[$name] = array('type' => 'select', 'size' => 1, 'value' => $value, 'option_list' => $option_list);
	}



	public function setOptions($field_name, $option_name_list) {
		foreach ($option_name_list as $option_value => $option_label) {
			$this->field_list[$field_name]['option_list'][$option_value] = $option_label;
		}
	}


	public function setLabels($field_label_list) {
		$field_name_list = array_keys($this->field_list);

		foreach ($field_label_list as $field_name => $label) {
			if (in_array($field_name, $field_name_list)) {
				$this->field_list[$field_name]['label'] = $label;
			}
		}
	}



	public function setPositions($field_position_list) {
		// musi być if bo automat czasem daje pustego arraya
		if ($field_position_list) {
			// jesli dostalismy tablice z kluczami typu int, to ukladamy tak jak leżą wartosci w tablicy
			if (strval(current($field_position_list)) !== strval(intval(current($field_position_list)))) {
				$field_position_list = array_combine($field_position_list, range(1, count($field_position_list)));
			}

			foreach ($field_position_list as $field_name => $position) {
				if (isset($this->field_list[$field_name])) {
					$this->field_list[$field_name]['position'] = $position;
				}
			}
		}
	}



	public function getValues() {
		$form_data = array();

		foreach ($this->field_list as $name => $field) {
			if (isset($field['value'])) {
				$form_data[$name] = $field['value'];
			}
		}

		return $form_data;
	}



	public function setValues($value_list) {
		foreach (array_keys($this->field_list) as $field_name) {
			if (isset($value_list[$field_name])) {
				$this->field_list[$field_name]['value'] = $value_list[$field_name];
			}
		}
	}


	/*
	$field = array('name' => '', 'type' => '', 'label' => '', 'value' => '', 'option_list' => '', 'size' => '', 'class' => '', 'form_id' => '');
	*/
	public static function getField($field, $form_id = null, $error_list = null, $alert_list = null) {
		if (empty($field['type'])) {
			$field['type'] = 'text';
		}
		
		$field_name = $field['name'];
		$field_id = $form_id.'_form_'.$field_name.'_field';
		$field_label = isset($field['label']) ? $field['label'] : $field_name;
		$field_class = isset($field['class']) ? $field['class'] : '';

		if ($field['type'] === 'raw') {
			return $field['content'];
		}

		if (empty($field['class_list'])) {
			$field['class_list'] = array();
			
			if (!empty($field['class'])) {
				$field['class_list'][] = $field['class'];
			}
		}
		
		if (in_array($field['type'], self::$set_field_type_list)) {
			$field['class_list'][] = 'set';
		}

		if (!empty($field['wrap_tag'])) {
			$wrap_tag = $field['wrap_tag'];
		} else {
			$wrap_tag = (in_array($field['type'], self::$set_field_type_list) ? 'fieldset' : 'p');
		}
		
		if (empty($field['value'])) {
			$field['value'] = '';
		}

		$return = '
			<'.$wrap_tag.' class="'.$field_name.' '.implode(' ', $field['class_list']).'" '
				. ((($field['type'] === 'hidden') || !empty($field['hidden'])) ? 'style="display: none;"' : '').'>
		';

		if (!empty($error_list)) {
			foreach (array_keys($error_list) as $error) {
				$return .= '<span class="error">'
					. (isset($alert_list[$error]) ? $alert_list[$error] : $error)
					. '</span>';
			}
		}
		
		switch ($field['type']) {

			case 'text': {
				$size = !empty($field['size']) ? $field['size'] : 35;
				$max = !empty($field['max']) ? $field['max'] : null;
				$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'.(isset($field['label']) ? $field['label'] : $field_name).'</label>';
				$return .= '<input 
					'.(isset($field['class']) ? ' class="'.$field['class'].'"' : '').'
					size="'.$size.'" 
					maxlength="'.($max ? $max : $size).'"
					type="'.$field['type'].'" 
					name="'.$field_name.'" 
					id="'.$form_id.'_form_'.$field_name.'_field" 
					value="'.(isset($field['value']) ? $field['value'] : '').'"'
					.(!empty($field['disabled']) ? ' disabled="disabled"' : '').'
					/>';
				break;
			}

			case 'select': {
				if (!isset($field['label']) || $field['label'] !== false) {
					$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'.(isset($field['label']) ? $field['label'] : $field_name).'</label>';
				}

				$return .= '<select name="'.$field_name.'" id="'.$form_id.'_form_'.$field_name.'_field"'.(!empty($field['size']) ? ' size="'.$field['size'].'"' : '').'>';
				
				if (empty($field['option_list'])) {
					e('option list empty', $field);
				}
				
				$field['value'] = (isset($field['value']) ? $field['value'] : strval(key($field['option_list'])));

				foreach ($field['option_list'] as $set_option_name => $set_option_label) {
					$return .= "\n".'<option value="'.$set_option_name.'"'.((strval($set_option_name) === strval($field['value'])) ? ' selected="selected"' : '').'>'.$set_option_label.'</option>';
				}

				$return .= '</select>';
				break;
			}

			case 'radio': {
				$return .= '<legend>'.(isset($field['label']) ? $field['label'] : $field_name).'</legend>';
				$field['value'] = (string) $field['value'];

				if (empty($field['value'])) {
					foreach (array_keys($field['option_list']) as $key) {
						if (empty($key)) {
							$field['value'] = $key;
							break;
						}
					}
				}

				if (!array_key_exists($field['value'], $field['option_list'])) {
					$field['value'] = strval(key($field['option_list']));
				}

				foreach ($field['option_list'] as $set_option_name => $set_option_label) {
					$return .= '<p class="'.$set_option_name.'">';
					$return .= 
						'<input type="radio" id="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field" '
						. 'name="'.$field_name.'" value="'.$set_option_name.'"'
						. (strval($set_option_name) === strval($field['value']) ? ' checked="checked"' : '').' />';
					$return .= '<label for="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field">'.$set_option_label.'</label>';
					$return .= '</p>';
				}

				break;
			}

			case 'textarea': {
				$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'
					. (isset($field['label']) ? $field['label'] : $field_name).'</label>'
					. '<textarea rows="'.(isset($field['rows']) ? $field['rows'] : '6')
					. '" cols="'.(isset($field['cols']) ? $field['cols'] : '100')
					. '" name="'.$field_name.'" class="'.$field_name
					. (!empty($field['class_list']) ? ' '.implode(' ', $field['class_list']) : '')
					. '" id="'.$form_id.'_form_'.$field_name.'_field">'
					. (strlen($field['value']) ? $field['value'] : '').'</textarea>';

				break;
			}

			case 'livesearch': {
				$return .= '
					<script type="text/javascript">
						$(document).ready(function() {
							$("#'.$field_id.'").focus(function() {
								$(this).css({\'width\':\'12em\'});
								var field = $(\'form [name="'.$field_name.'"]\').get(0);
								var new_source = field.base_source;
								for (var loop = 0; loop < field.param_field_list.length; loop++) {
									new_source += \'&\' + field.param_field_list[loop] + \'=\' + $(\'form [name="\' + field.param_field_list[loop] + \'"]\').val();
								}
								$("#'.$field_id.'").autocomplete(\'option\', \'source\', new_source);
							});
							$("#'.$field_id.'").blur(function() {
								$(this).css({\'width\':\'5em\'});
								$(this).val(\'\');
							});
							$("#'.$field_id.'").autocomplete({
								  source: \''.$field['source'].'\'
								, select: function(event, ui) {
									$(\'form [name="'.$field_name.'"]\').val(ui.item.id);
									$("span.value_label.'.$field_name.'").text(ui.item.value);
									$(\'form [name="'.$field_name.'"]\').change();
									$(this).blur();
									return false;
								}
							});
							$("span.value_label.'.$field_name.'").click(function() {
								$("#'.$field_id.'").focus();
							});
							$("#'.$form_id.'_form_'.$field_name.'_clear_button'.'").click(function() {
								$("span.value_label.'.$field_name.'").text("");
								$(\'form [name="'.$field_name.'"]\').val("");
								$("#'.$field_id.'").focus();
							});
							var field = $(\'form [name="'.$field_name.'"]\').get(0);
							field.param_field_list = ['.(empty($field['param_field_list']) ? '' : '"'.implode('", "', $field['param_field_list']).'"').'];
							field.base_source = \''.$field['source'].'\';
						});
					</script>
					<label for="'.$field_id.'">'.$field_label.'</label>
					<input type="hidden" name="'.$field_name.'" value="'.(isset($field['value']) ? $field['value'] : '').'" />
					<span class="value_label '.$field_name.'">'.(isset($field['display']) ? $field['display'] : '').'</span>
					<input class="'.$field_class.' livesearch" id="'.$field_id.'" name="'.$field_name.'_livesearch_query" type="text" value="'.(isset($field['query_value']) ? $field['query_value'] : '').'" />
					<button type="button" id="'.$form_id.'_form_'.$field_name.'_clear_button'.'" class="livesearch clear" title="Wyczyść"><img src="'.SITE_URL.'img/icons/tango/broom.png" /></button>
					';
				break;
			}

			case 'liveselect': {
				$selected_html = '';
				foreach ($field['value_list'] as $id => $name) {
					$selected_html .= '<p title="'.xa::say('Usuń z listy').'"><span class="id">'.$id.'</span><span class="name">'.$name.'</span></p>';
				}

				$return .= '
					<label for="'.$field_id.'">'.$field_label.'</label>
					<input type="hidden" name="'.$field_name.'" value="'.(!empty($field['value_list']) ? implode(',', array_keys($field['value_list'])) : '').'" />
					<input class="liveselect" id="'.$field_id.'" name="'.$field_name.'_liveselect_query" type="text" size="25" />
					<div class="clear"></div>
					<div class="found">
					</div>
					<div class="selected">
						'.$selected_html.'
					</div>
					<div class="clear"></div>
					<script type="text/javascript">
						prepareLiveSelect(\''.$field_id.'\', \''.$field_name.'\', \''.$field['source'].'\');
					</script>
				';
				break;
			}

			case 'multilivesearch': {
				$return .= '<legend>'.$field_label."</legend>\n".'
					<script type="text/javascript">
						$(document).ready(function() {
						
							var query_input = $("#'.$field_id.'").get(0);
							
							query_input.isSearching = false;
							query_input.countdown = 0;
							query_input.found = true;
							
							query_input.load = function() {
								$.ajax({
									url: \''.$field['source'].'\',
									dataType: \'json\',
									data: {\'query\': $("#'.$field_id.'").val()},
									success: function(json_data) {
										json_data.reverse();
										var options = \'\';
										$(\'fieldset.'.$field_name.' input[type="checkbox"]\').not(\':checked\').parent().remove();
										var present_id_list = [];
										var present_field_list = $(\'fieldset.'.$field_name.' input[type="checkbox"]\').get();
										for (var field_loop = 0; field_loop < present_field_list.length; field_loop++) {
											present_id_list.push(present_field_list[field_loop].name.match(/\[(\d+)\]/)[1]);
										}
										var after_div = $("#'.$field_id.'").parent().find(\'div.clear\').get(0);
										for (var loop in json_data) {
											var present = false;
											for (var present_id_loop = 0; present_id_loop < present_id_list.length; present_id_loop++) {
												if (present_id_list[present_id_loop] == json_data[loop].id) {
													present = true;
													break;
												}
											}
											if (!present) {
												var field_id = \'company_edit_form_'.$field_name.'_list_\' + json_data[loop].id + \'_field\';
												var field = \'<p><input type="checkbox" id="\' + field_id + \'" name="'.$field_name.'[\' + json_data[loop].id + \']" value="1" />\'
													+ \'<label style="color: #06d;" for="\' + field_id + \'">\' + json_data[loop].value + \'</label></p>\';
												$(after_div).after(field);
												$(\'#company_edit_form_'.$field_name.'_list_\' + json_data[loop].id + \'_field\').change(function() {
													strikeLabel(this);
												});
											}
										}
										query_input.isSearching = false;
										query_input.found = true;
									}
								});
							}
							
							query_input.interval = setInterval(function() {
								var query_input = $("#'.$field_id.'").get(0);
								if (!query_input.found) {
									if (!query_input.isSearching && query_input.countdown <= 0 && query_input.value.length > 2) {
										query_input.isSearching = true;
										query_input.load();
									} else {
										query_input.countdown = query_input.countdown - 50;
									}
								}
							}, 50);

							$(query_input).keypress(function() {
								this.countdown = 800;
								this.found = false;
							});
							
							$(\'form fieldset.'.$field_name.'_list input[type="checkbox"]\').change(function() {
								$(this).parent().find(\'label\').css(\'text-decoration\', (this.checked ? \'none\' : \'line-through\'));
							});
						});
					</script>
					<input class="multilivesearch" id="'.$field_id.'" name="'.$field_name.'_multilivesearch_query" type="text" size="25" />
					<div class="clear"></div>';

				foreach ($field['option_list'] as $set_option_name => $set_option_label) {
					$return .= '<p>'
						. '<input type="checkbox" id="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field" name="'.$field_name.'['.$set_option_name.']" value="1" '.(in_array($set_option_name, $field['value_list']) ? 'checked="checked"' : '').' />'
						. "\n".'<label for="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field">'.$set_option_label.'</label>'
						. '</p>'."\n";
				}

				break;
			}

			case 'file': {
				$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'.(isset($field['label']) ? $field['label'] : $field_name).'</label>';
				$return .= '<input class="'.(isset($field['class']) ? $field['class'] : '').'" type="'.$field['type'].'" name="'.$field_name.'" id="'.$form_id.'_form_'.$field_name.'_field" />';
				break;
			}

			case 'set': {
				$return .= '<legend>'.(isset($field['label']) ? $field['label'] : $field_name)."</legend>\n";
				foreach ($field['option_list'] as $set_option_name => $set_option_label) {
					$return .= '<p>';
					$return .= '<input type="checkbox" id="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field" name="'.$field_name.'['.$set_option_name.']" value="1" '.(in_array($set_option_name, $field['value_list']) ? 'checked="checked"' : '').' />';
					$return .= '<label for="'.$form_id.'_form_'.$field_name.'_'.$set_option_name.'_field">'.$set_option_label.'</label>';
					$return .= "</p>\n";
				}
				break;
			}
			
			case 'checkbox': {
				$return .= '<input class="'.(isset($field['class']) ? $field['class'] : '').'" type="checkbox" name="'.$field_name.'" id="'.$form_id.'_form_'.$field_name.'_field" value="1" '.(!empty($field['value']) ? 'checked="checked"' : '').' />';
				if (isset($field['label'])) {
					$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'.$field['label'].'</label>';
				}
				break;
			}

			case 'button': {
				if (!isset($field['label']) || $field['label'] !== false) {
					$return .= '<label for="'.$form_id.'_form_'.$field_name.'_field">'.(isset($field['label']) ? $field['label'] : $field_name).'</label>';
				}
				$return .= '<button type="'.$field['type'].'" name="'.$field_name.'"	id="'.$form_id.'_form_'.$field_name.'_button">'.$field['value'].'</button>';
				break;
			}
			
			default: {
				$return .= (isset($field['label']) ? '<label for="'.$form_id.'_form_'.$field_name.'_field">'.$field['label'].'</label>' : '');
				$return .= '<input type="'.$field['type'].'" name="'.$field_name.'" id="'.$form_id.'_form_'.$field_name.'_field" value="'.(isset($field['value']) ? $field['value'] : '').'"/>';
			}
		}
		$return .= '</'.$wrap_tag.">\n";
		return $return;
	}



	public function printout () {
		$form_data = $this->getValues() + $this->form_data;
		$this->setValues($form_data);

		foreach (array_keys($this->field_list) as $field_name) {
			$this->field_list[$field_name]['name'] = $field_name;
		}

		echo '<form action="'.$this->action.'" id="'.$this->id.'" method="'.$this->method.'" '
			. ($this->has_file ? 'enctype="multipart/form-data"' : '')
			. ' class="'.implode(' ', $this->class_list).'">
				<div style="display: none;">
				'.XA_XHTML_Form::getField($this->field_list['tmpdata_id'], $this->id).'
				</div>';

		if (file_exists($template_filename = MODULE_PATH.'templates/forms/'.$this->template.'.php')) {
			include($template_filename);
		} else {
			include(APP_PATH.$this->template.'.php');
		}
		
		echo '</form>';
	}



	public function out () {
		if ($this->form_template) {
			flush();
			$form_data = $this->getValues() + $this->form_data;
			$this->setValues($form_data);

			foreach (array_keys($this->field_list) as $field_name) {
				$this->field_list[$field_name]['name'] = $field_name;
			}

			ob_start();
			include(APP_PATH.$this->form_template);
			$return = ob_get_contents();
			ob_end_clean();
		} else {
			$return = '<form action="'.$this->action.'" id="'.$this->id.'" method="'.$this->method.'" '.($this->has_file ? 'enctype="multipart/form-data"' : '').' class="'.implode(' ', $this->class_list).'">';
			$return .= ($this->title ? '<h3>'.$this->title.'</h3>' : '');
			
			// sortowanie po ['position']
			$field_sort_list = array();
			$last_postition = 1000;

			foreach ($this->field_list as $name => $field) {
				$field['name'] = $name;

				if (empty($field['position'])) {
					$field['position'] = $last_postition++;
				}

				$field_sort_list[$field['position']] = $field;
			}

			ksort($field_sort_list);
			$this->field_list = array();

			foreach ($field_sort_list as $field) {
				$this->field_list[$field['name']] = $field;
			}

			foreach ($this->field_list as $field_name => $field) {
				$field['name'] = $field_name;
				$error_list = (isset($this->error_list[$field_name]) ? $this->error_list[$field_name] : null);
				$alert_list = (isset($this->alert_list[$field_name]) && is_array($this->alert_list[$field_name]) ? $this->alert_list[$field_name] : $this->alert_list);
				$return .= self::getField($field, $this->id, $error_list, $alert_list);
			}

			$return .= '</form>';
		}

		return $return;
	}
}
